package cn.buddha.jeres.server.intercept;

import cn.buddha.jeres.server.component.EsComponent;
import cn.buddha.jeres.server.config.EsCommConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.ui.ModelMap;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.View;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @ClassName EsHandlerIntercept
 * @Author 友野浩二
 * @Date 2019/12/26 0:54
 * @Description 拦截器: 使用Spring提供的拦截器(HandlerInterceptor)进行更加精细的控制
 * @Version 1.0
 */
@Component
@Slf4j
public class EsHandlerIntercept implements HandlerInterceptor {

    @Resource
    private EsComponent esComponent;

    @Resource
    private EsCommConfig esCommConfig;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("Tong Eureka Server preHandle: 在业务处理器处理请求之前被调用,即在调用controller之前调用");
        return true;
    }

    /**
     * @Author 友野浩二
     * @Description //
     * @Date 2019/12/26 00:50
     * @Param request
     * @Param response
     * @Param handler
     * @Param modelAndView: 用来存储处理完后的结果数据，以及显示该数据的视图。Model代表模型，View代表视图。
     * @return void
     **/
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        // 当Controller层返回的是页面时
        if (null != modelAndView) {
            String viewName = modelAndView.getViewName();// 视图名
            View view = modelAndView.getView();
            ModelMap modelMap = modelAndView.getModelMap();// 返回给前端页面的数据模型
            Map<String, Object> map = modelAndView.getModel();

            log.info("viewName: {}", viewName);
            log.info("modelMap: {}", modelMap);
            log.info("map: {}", map);
            log.info("view: {}", view);

            // 当返回视图名为 与 interceptViewList 集合中的元素相同时(参见控制器org.springframework.cloud.netflix.eureka.server.EurekaController的status)
            if (this.esCommConfig.getView().containsValue(viewName)) {
                log.info("哈哈哈哈哈哈啊哈哈哈");
                // 对 返回模型中的 某些属性 进行个性化处理
                // 如果modelMap中添加的 map 的 key 重复了,则后者会覆盖前者对应的value
                modelMap.addAllAttributes(this.esComponent.addElement());
            }
        }

        log.info("Tong Eureka Server postHandle: 在业务处理器(Controller)处理请求执行完成后，生成视图之前执行。" +
                "如果控制器Controller出现了异常，则不会执行此方法");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("Tong Eureka Server afterCompletion: 不管有没有异常，请求调用完成后回调方法，即在视图渲染完成后回调");
    }

}
